package com.life.notes.config.log;

import com.google.gson.Gson;
import io.swagger.annotations.ApiOperation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author lishuqian
 * @date 2020/6/15
 */
@Aspect
@Component
public class ControllerLogAspect {
    private static final Logger log = LoggerFactory.getLogger(ControllerLogAspect.class);
    private Gson gson = new Gson();
    private ThreadLocal<Long> startTime = new ThreadLocal();

    public ControllerLogAspect() {
    }

    @Pointcut("@annotation(io.swagger.annotations.ApiOperation)")
    private void controllerAspect() {
    }

    @Before("controllerAspect()")
    public void methodBefore(JoinPoint joinPoint) {
        this.startTime.set(System.currentTimeMillis());
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature)signature;
        Method method = methodSignature.getMethod();
        String description = (method.getAnnotation(ApiOperation.class)).value();
        log.info("===============Controller层请求内容===============");
        log.info("请求地址:" + request.getRequestURL().toString());
        log.info("请求方式:" + request.getMethod());
        log.info("请求类方法:" + signature);
        log.info("请求类方法描述:" + description);
        log.info("请求类方法参数:" + Arrays.toString(joinPoint.getArgs()));
        log.info("===============Controller层请求内容===============");
    }

    @AfterReturning(
            returning = "object",
            pointcut = "controllerAspect()"
    )
    public void methodAfterReturing(Object object) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        log.info("===============Controller层响应内容===============");
        log.info("请求地址:" + request.getRequestURL().toString());
        log.info("请求方式:" + request.getMethod());
        log.info("响应内容:" + this.gson.toJson(object));
        log.info("请求处理时间为:" + (System.currentTimeMillis() - (Long)this.startTime.get()));
        log.info("===============Controller层响应内容===============");
    }
}
